package paper.web.security;

import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;

import keter.domain.Role;
import keter.web.security.AccountAdapter;
import keter.web.security.AuthorityAdapter;

import org.springframework.security.core.GrantedAuthority;

import paper.dao.UserDao;
import paper.domain.User;


/**
 * Adapts User model from pl.edu.agh.mea.domain package to make it usable in
 * Spring Security authentication mechanism.
 * 将应用的User转换为Spring的User
 * @author Dawid Fatyga
 * 
 */
public class UserAdapter extends AccountAdapter{
	private static final long serialVersionUID = 1L;

	transient private User user;
	transient private UserDao dao;
	
	public UserAdapter() {
	}

	public UserAdapter(User user, UserDao dao) {
		this.user = user;
		this.dao = dao;
		setAccount(user.getAccount());//将“账户”注入框架
	}

	/**
	 * Converts collection of Authorities into collection of GrantedAuthorities
	 * usable in authentication mechanism.
	 * 
	 * @param authorities
	 *            collection of authorities
	 * @return collection of granted authorities
	 */
	private Collection<GrantedAuthority> toGrantedAuthorities(Collection<Role> authorities) {
		Set<GrantedAuthority> grantedAuthorities = new TreeSet<GrantedAuthority>();
		for (Role authority : authorities) {
			grantedAuthorities.add(new AuthorityAdapter(authority));
		}
		return grantedAuthorities;
	}
	
	/**
	 * @param force
	 *            allows to fetch user from database (not from cache)
	 * @return user instance
	 */
	public User getUser(boolean force) {
		if (force) {
			if (user == null || dao == null) {
				throw new RuntimeException(new NullPointerException("user or userDao is null"));
			}
			user = dao.findOne(user.getId());
		}
		return user;
	}

	@Override
	public Collection<GrantedAuthority> getAuthorities() {
		return toGrantedAuthorities(user.getAccount().getRoleList());
	}

	@Override
	public String getPassword() {
		return user.getAccount().getPassword();
	}

	@Override
	public String getUsername() {
		return user.getAccount().getName();//系统采用“账号”作为登录验证
	}
}